﻿#ifndef _PHOENIX_H
#define _PHOENIX_H

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <typeinfo>
#include<semaphore.h>

#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

#include "armor/Inc/ArmorDector.h"
#include "utilities/Inc/general.h"
#include "utilities/Inc/opencv_extend.h"
#include "serials/Inc/serial.h"
#include "utilities/Inc/log.h"
#include "main/Inc/img_buffer.h"
#include "camera/Inc/camera.h"
#include"buff/Inc/Buff.h"
#include"workstate/Inc/state.h"

#include<QThread>
#include<QMutex>

// Phoenix接口，方便之后添加兵种
class Phoenix  :public QObject
{
    Q_OBJECT
public:

    Phoenix();

    ~Phoenix();

    //海康相机读取图片函数，不需要更改-------生产者
    void Produce();
    //神符打击需要的第二摄像头
    void  ProduceBuff();
    //纯虚函数从下位机读取数据，需要在子类中重写（不同兵种不同通信）
    virtual void Sense() = 0;

    //对获取到的图片进行一系列处理，同样是纯虚函数，需要重写 -------消费者
	virtual void Consume() = 0;
    
    Mat getImage();

    shared_ptr<Mycamera> getMyCamera();

    shared_ptr<Work> getWorkState();


private:
    /* 相机 */
    shared_ptr<Mycamera> _mycamera;
    shared_ptr<Mycamera> _mycamerabuff;
    /* Angle solver */
    //PNPSolver p4pSolver;

//    //神符识别
//    BuffDetector _detect;
//    BuffDetector _detect2;
protected:
    Mat _src;
    Mat _src2;
    /*图片缓存*/
    ImgBuffer _buffer;
    ImgBuffer _bufferBuff;

    /* 串口 */
    Serial _serial;

    //设计模式（状态模式）  ， 车不同状态转换
    shared_ptr<Work> _workState;
    volatile  int _task;
    volatile int _shootTask;

    //信号量，线程同步（可以用互斥量，这里因为我刚刚学了信号量，用了信号量的话图片缓冲区就没用了）
    sem_t sem_pro;
    sem_t sem_com;

    //互斥量
    QMutex _mutex;

    //debug用来计时的类，查看帧率
    CELLTimestamp _tTime;
signals:
    void getImage(Mat src);
    void getImageBottom(Mat src);
    void waitkey(int time);
};


//兵种工厂（抽象工厂） 用来实例化我们的兵种对象
class RMFactory
{
public:
    RMFactory(){}
    ~RMFactory(){}
    virtual shared_ptr<Phoenix> creatPhoenix() = 0;
}; 

#endif


